package com.epam.ws.anatomist.message;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.epam.ws.anatomist.common.WsAnatomistUtil;
import com.epam.ws.anatomist.common.exception.DataSourceException;
import com.epam.ws.anatomist.common.exception.ErrorMessages;
import com.epam.ws.anatomist.common.exception.ResourceProcessingException;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class TemplateEntity
{

	public static final String PATH_PREFIX = "/";

	private static final Logger LOGGER = Logger.getLogger(TemplateEntity.class);

	private String templatePath;

	private String dataSourcePath;

	private Template template;

	private Properties dataSource;

	public void setTemplatePath(String templatePath)
	{
		if (templatePath == null || templatePath.isEmpty())
		{
			LOGGER.error(ErrorMessages.TEMPLATE_PATH_ERROR);
			throw new DataSourceException(ErrorMessages.TEMPLATE_PATH_ERROR);
		}
		this.templatePath = templatePath;
		try
		{
			Configuration templateConfig = new Configuration();
			templateConfig.setClassForTemplateLoading(this.getClass(), PATH_PREFIX);
			this.template = templateConfig.getTemplate(templatePath);
		}
		catch (IOException e)
		{
			final String errorMessage = String.format(ErrorMessages.GET_TEMPLATE_ERROR, templatePath);
			LOGGER.error(errorMessage);
			throw new DataSourceException(errorMessage, e);
		}
	}

	public void setDataSourcePath(String dataSourcePath)
	{
		this.dataSourcePath = dataSourcePath;
		this.dataSource = new Properties();
		InputStream sourceInputStream = null;
		try
		{
			if (dataSourcePath != null)
			{
				sourceInputStream = WsAnatomistUtil.getResourceAsStream(dataSourcePath);
				this.dataSource.load(sourceInputStream);
				PropertiesGenerator.scanPropertiesAndGenerate(this.dataSource);
			}
		}
		catch (IOException e)
		{
			final String errorMessage = String.format(ErrorMessages.LOAD_PROPERTIES_ERROR, dataSourcePath);
			LOGGER.error(errorMessage);
			throw new DataSourceException(errorMessage, e);
		}
		finally
		{
			if (sourceInputStream != null)
			{
				try
				{
					sourceInputStream.close();
				}
				catch (IOException e)
				{
					LOGGER.error(ErrorMessages.INPUT_STREAM_CLOSING_ERROR);
					throw new ResourceProcessingException(ErrorMessages.INPUT_STREAM_CLOSING_ERROR, e);
				}
			}
		}
	}

	public Template getTemplate()
	{
		return this.template;
	}

	public Properties getDataSource()
	{
		return this.dataSource;
	}

	public void setDataSource(Properties dataSource)
	{
		this.dataSource = dataSource;
	}

	public String getTemplatePath()
	{
		return this.templatePath;
	}

	public String getDataSourcePath()
	{
		return this.dataSourcePath;
	}

	public TemplateEntity usingParameters(Properties dataSource)
	{
		if (this.dataSource == null)
		{
			this.dataSource = new Properties();
		}
		this.dataSource.putAll(dataSource);
		PropertiesGenerator.scanPropertiesAndGenerate(this.dataSource);
		return this;
	}

	public TemplateEntity usingParameter(String name, String value)
	{
		if (this.dataSource == null)
		{
			this.dataSource = new Properties();
		}
		else
		{
			this.dataSource.put(name, value);
		}
		return this;
	}

}
